﻿using System;

// 定义成绩打印委托：参数为学生对象，返回是否打印成功
public delegate bool GradePrint(Student s);

// 学生类
public class Student
{
    // 学生基本信息
    public string Name { get; set; }      // 姓名
    public int Id { get; set; }          // 学号
    public double Math { get; set; }     // 数学成绩
    public double English { get; set; }  // 英语成绩
    public double Chinese { get; set; }  // 语文成绩

    // 成绩打印委托属性（用于关联打印模板）
    public GradePrint GradePrinter { get; set; }

    // 构造函数
    public Student(int id, string name, double math, double english, double chinese)
    {
        Id = id;
        Name = name;
        Math = math;
        English = english;
        Chinese = chinese;
    }

    // 打印成绩的方法（通过委托调用具体模板）
    public bool PrintGrade()
    {
        if (GradePrinter != null)
        {
            return GradePrinter(this); // 调用委托关联的打印模板
        }
        Console.WriteLine("未设置打印模板，无法打印成绩");
        return false;
    }
}

// 成绩单类（包含多种打印模板）
public class GradeReport
{
    // 模板1：按科目顺序打印（数学→英语→语文）
    public static bool PrintBySubjectOrder(Student s)
    {
        if (s == null)
        {
            Console.WriteLine("学生信息为空，打印失败");
            return false;
        }

        Console.WriteLine("=== 科目顺序成绩单 ===");
        Console.WriteLine($"学号：{s.Id}  姓名：{s.Name}");
        Console.WriteLine($"数学：{s.Math}");
        Console.WriteLine($"英语：{s.English}");
        Console.WriteLine($"语文：{s.Chinese}");
        Console.WriteLine("======================\n");
        return true;
    }

    // 模板2：按成绩高低排序打印
    public static bool PrintByScoreOrder(Student s)
    {
        if (s == null)
        {
            Console.WriteLine("学生信息为空，打印失败");
            return false;
        }

        // 存储科目和成绩的键值对
        var scores = new (string Subject, double Score)[]
        {
            ("数学", s.Math),
            ("英语", s.English),
            ("语文", s.Chinese)
        };

        // 简单排序（从高到低）
        Array.Sort(scores, (a, b) => b.Score.CompareTo(a.Score));

        Console.WriteLine("=== 成绩排序成绩单 ===");
        Console.WriteLine($"学号：{s.Id}  姓名：{s.Name}");
        foreach (var item in scores)
        {
            Console.WriteLine($"{item.Subject}：{item.Score}");
        }
        Console.WriteLine("======================\n");
        return true;
    }

    // 模板3：简洁版打印（只显示总分）
    public static bool PrintSimpleVersion(Student s)
    {
        if (s == null)
        {
            Console.WriteLine("学生信息为空，打印失败");
            return false;
        }

        double total = s.Math + s.English + s.Chinese;
        Console.WriteLine("=== 简洁版成绩单 ===");
        Console.WriteLine($"学号：{s.Id}  姓名：{s.Name}");
        Console.WriteLine($"总分：{total}  平均分：{total / 3:F2}");
        Console.WriteLine("======================\n");
        return true;
    }
}

// 测试程序
class Program
{
    static void Main(string[] args)
    {
        // 创建学生对象
        Student student1 = new Student(101, "张三", 92, 88, 95);
        Student student2 = new Student(102, "李四", 76, 90, 82);

        // 学生1选择：按科目顺序打印
        student1.GradePrinter = GradeReport.PrintBySubjectOrder;
        Console.WriteLine("学生1的成绩打印结果：");
        student1.PrintGrade();

        // 学生1更换模板：按成绩高低打印
        student1.GradePrinter = GradeReport.PrintByScoreOrder;
        Console.WriteLine("学生1更换模板后的打印结果：");
        student1.PrintGrade();

        // 学生2选择：简洁版打印
        student2.GradePrinter = GradeReport.PrintSimpleVersion;
        Console.WriteLine("学生2的成绩打印结果：");
        student2.PrintGrade();

        // 测试未设置模板的情况
        Student student3 = new Student(103, "王五", 85, 80, 90);
        Console.WriteLine("学生3（未设置模板）的打印结果：");
        student3.PrintGrade();
    }
}